/////////////////////////////////////////////////////////////////////////////////////////////
// Filename: Util.h
// (c) Dave Ottley, 2012. All rights reserved.
/////////////////////////////////////////////////////////////////////////////////////////////
#ifndef UTIL_H
#define UTIL_H

///////////////////////////
//		INCLUDES
///////////////////////////
#include <windows.h>
#include <dxerr.h>
#include <assert.h>
#include <xnamath.h>
#include <string>


///////////////////////////
//		MY INCLUDES
///////////////////////////


//--------------------------------------------------------------------------------------
// Simple Error Checker
//--------------------------------------------------------------------------------------
#if defined(DEBUG) || defined(_DEBUG)
	#ifndef HR
	#define HR(x)                                              \
	{                                                          \
		HRESULT hr = (x);                                      \
		if(FAILED(hr))                                         \
		{                                                      \
			DXTrace(__FILE__, (DWORD)__LINE__, hr, L#x, true); \
		}                                                      \
	}
	#endif

#else
	#ifndef HR
	#define HR(x) (x)
	#endif
#endif 



//--------------------------------------------------------------------------------------
// Convenience Macro for releasing objects with a Release() member and
// COM Objects
// DOES NOT WORK WITH CONST POINTERS
//--------------------------------------------------------------------------------------
#if defined(DEBUG) || defined (_DEBUG)
	#ifndef ReleaseCOM
	#define ReleaseCOM(x)									\
	{														\
		if(x != NULL)										\
		{													\
			x->Release();									\
			x = 0;											\
		}													\
		else												\
		{													\
			HRESULT hr = S_OK;								\
			DXTrace(__FILE__, (DWORD)__LINE__, hr,			\
			L"Attempting to Release a NULL pointer!", true);\
		}													\
	}
	#endif

#else
	#ifndef ReleaseCOM
	#define ReleaseCOM(x) { if(x) { x->Release(); x = 0; } }
	#endif
#endif

//---------------------------------------------------------------------------------------
// Convenience macro for deleting objects.
//---------------------------------------------------------------------------------------
#if defined(DEBUG) || defined (_DEBUG)
	#ifndef SafeDelete
	#define SafeDelete(x)									\
	{														\
		if(x)												\
		{													\
			delete x;										\
			x = 0;											\
		}													\
		else												\
		{													\
			HRESULT hr = S_OK;										\
			DXTrace(__FILE__, (DWORD)__LINE__, hr,			\
			L"Attempting to Delete a NULL pointer!", true);	\
		}													\
	}
	#endif

#else
	#ifndef SafeDelete
	#define SafeDelete(x) { delete x; x = 0; }
	#endif
#endif

//---------------------------------------------------------------------------------------
// Convenience macro for clamping floats
//---------------------------------------------------------------------------------------
namespace Util
{
	// Has side effects on x
	inline float ClampFloat(float& x, float min, float max) { return x = (((x) > (max)) ? (max) : (((x) < (min)) ? (min) : (x))); }
	std::wstring AppendAssetsDirectory(const wchar_t * filename);
}
	
//--------------------------------------------------------------------------------------
// Convenient Colors
//--------------------------------------------------------------------------------------
namespace Colors
{
	XMGLOBALCONST XMVECTORF32 White     = {1.0f, 1.0f, 1.0f, 1.0f};
	XMGLOBALCONST XMVECTORF32 Black     = {0.0f, 0.0f, 0.0f, 1.0f};
	XMGLOBALCONST XMVECTORF32 Red       = {1.0f, 0.0f, 0.0f, 1.0f};
	XMGLOBALCONST XMVECTORF32 Green     = {0.0f, 1.0f, 0.0f, 1.0f};
	XMGLOBALCONST XMVECTORF32 Blue      = {0.0f, 0.0f, 1.0f, 1.0f};
	XMGLOBALCONST XMVECTORF32 Yellow    = {1.0f, 1.0f, 0.0f, 1.0f};
	XMGLOBALCONST XMVECTORF32 Cyan      = {0.0f, 1.0f, 1.0f, 1.0f};
	XMGLOBALCONST XMVECTORF32 Magenta   = {1.0f, 0.0f, 1.0f, 1.0f};

	XMGLOBALCONST XMVECTORF32 Silver    = {0.75f, 0.75f, 0.75f, 1.0f};
	XMGLOBALCONST XMVECTORF32 LightSteelBlue = {0.69f, 0.77f, 0.87f, 1.0f};
}


#endif // UTIL_H


